package com.cloud.screen.api.service.impl;


import com.cloud.screen.api.entity.UnitInfo;
import com.cloud.screen.api.mapper.HumanInfoMapper;
import com.cloud.screen.api.mapper.UnitInfoMapper;
import com.cloud.screen.api.service.HumanInfoService;
import com.cloud.screen.common.result.SelectItem;
import com.cloud.screen.common.utils.SessionHelper;
import com.cloud.screen.interfaces.FeignClientSystem;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class HumanInfoServiceImpl implements HumanInfoService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private UnitInfoMapper unitInfoMapper;

    @Autowired
    private HumanInfoMapper humanInfoMapper;

    @Autowired
    private FeignClientSystem feignClientSystem;

    @Override
    public List<Map<String, Object>> getPatrolOrganization(Long regionid) {

        String sql = "SELECT count(a.unit_id) as specialCount,\n" +
                "count(b.unit_id) as commomCount\n" +
                "FROM\n" +
                "(SELECT  ui.* FROM human_info hi LEFT JOIN unit_info ui ON hi.unit_id = ui.unit_id\n" +
                "WHERE hi.human_type = '02' AND ui.senior_id =" + regionid +"  AND ui.unit_type_id = 6)a\t\n" +
                "LEFT JOIN\n" +
                "(SELECT ui.* FROM human_info hi LEFT JOIN unit_info ui ON hi.unit_id = ui.unit_id\n" +
                "WHERE hi.human_type = '02' AND ui.senior_id = " + regionid +" AND ui.unit_type_id = 7)b ON a.senior_id  = b.senior_id";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }

    @Override
    public Map<String, Object> getPatrolAuthorityEnforcement(Long regionid) {
        if (regionid == null){
            regionid = 1L;
        }
        String sql = "SELECT count(*) AS  `count` FROM\tunit_info u WHERE u.unit_type_id = 5  AND u.delete_flag != 1 AND u.unit_code LIKE '%"+regionid+"%'" +
                "UNION SELECT count(*) AS `count` FROM\tunit_info u WHERE \tu.unit_type_id = 6  AND u.delete_flag != 1 AND u.unit_code LIKE '%"+regionid+"%'";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        Map<String, Object> map = new HashedMap();
        map.put("supervisory",list.size() > 0 ?list.get(0).get("count"):0);
        map.put("watchdog",list.size() > 1 ?list.get(1).get("count"):0);
        return map;
    }

    @Override
    public  Map<String, Object> getInfoGeneral(Long regionid) {
        // 执法机关
        if (regionid == null){
            regionid = 1L;
        }
        Example queryExample = new Example(UnitInfo.class);
        Example.Criteria queryCriteria = queryExample.createCriteria();
        queryCriteria.andNotEqualTo("deleteFlag","1");
        List<Long> str = new ArrayList<>();
        str.add(2L);
        str.add(4L);
        queryCriteria.andIn("unitTypeId", str);
        queryCriteria.andLike("unitCode", "%" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%");
        int count = unitInfoMapper.selectCountByExample(queryExample);
        // 监督机构
        List<String> string = new ArrayList<>();
        string.add("6");
        string.add("5");
        Example queryExample2 = new Example(UnitInfo.class);
        Example.Criteria queryExampleCriteria1 = queryExample2.createCriteria();
        queryExampleCriteria1.andNotEqualTo("deleteFlag","1");
        queryExampleCriteria1.andIn("unitTypeId",string);
        queryExampleCriteria1.andLike("unitCode", "%" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%");
        int count2 = unitInfoMapper.selectCountByExample(queryExample2);
        // 执法人员
        String sql = "select count(*) from human_info hu where hu.unit_code like '" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%'  AND  hu.delete_flag = 0 AND  hu.is_law_human = 1 AND  hu.human_type != '00'";
        Integer count3 = jdbcTemplate.queryForObject(sql, Integer.class);
        // 监督人员

        String u =  " ui.unit_code like '" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%'";
        String sqls = "SELECT count(1) AS  `count` FROM human_info hio  LEFT JOIN unit_info ui ON hio. unit_id = ui.unit_id\n" +
                "        WHERE hio.human_type='02' AND hio.delete_flag != 1\n" +
                "        AND "+u+"";
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sqls);
        int count4 = mapList.get(0).get("count")==null?0:Integer.parseInt(mapList.get(0).get("count").toString());
        List<Map<String, Object>> returnList = new ArrayList<>();
        Map<String, Object> countMap = new HashedMap();
        countMap.put("unit",count);
        countMap.put("authority",count2);
        countMap.put("law",count3);
        countMap.put("supervise",count4);
        returnList.add(countMap);
        return countMap;
    }

    @Override
    public Map<String, Object> getInfoUnitSummary(Integer isSupervise, Long regionid) {
        if (regionid == null){
            regionid = 1L;
        }
        String unitTypeFilter = "";
        if (isSupervise == 0) {
            unitTypeFilter = " uf.unit_type_id in (2,4)";
        }else if(isSupervise == 2){
            unitTypeFilter = "  uf.unit_type_id = 2 ";
        }
//       { authority: '行政执法职权数', permit: '行政许可数', check: '检查事项数', supervise: '监管事项数' };
        UnitInfo unitInfo = unitInfoMapper.selectByPrimaryKey(regionid);
        String unitFilter =  " uf.unit_code like '" + unitInfo.getUnitCode() + "%'";
        String inspectSql = "SELECT count(*) AS `check` FROM unit_inspect ui LEFT JOIN unit_info uf ON ui.unit_id = uf.unit_id WHERE uf.delete_flag != 1 AND "+unitTypeFilter+" AND "+unitFilter+"";
        Integer check = jdbcTemplate.queryForObject(inspectSql, Integer.class);
        String permitSql = "SELECT count(*) AS permit FROM unit_permit ui LEFT JOIN unit_info uf ON ui.permit_unit_id = uf.unit_id WHERE uf.delete_flag != 1 AND "+unitTypeFilter+" AND "+unitFilter+"";
        Integer permit = jdbcTemplate.queryForObject(permitSql, Integer.class);
        String checkSql = "SELECT count(*) AS `authority` FROM unit_power ui LEFT JOIN unit_info uf ON ui.unit_id = uf.unit_id WHERE uf.delete_flag != 1 AND "+unitTypeFilter+" AND "+unitFilter+"";
        Integer authority = jdbcTemplate.queryForObject(checkSql, Integer.class);

        //总监管事项数
        String serSql = "SELECT social_credit_code FROM unit_info WHERE unit_code like '" + unitInfo.getUnitCode() + "%'  AND unit_type_id = 2  AND delete_flag = 0 AND  social_credit_code != ''";
        List<Map<String, Object>> serList = jdbcTemplate.queryForList(serSql);
        List<String> socialList = new ArrayList<>();
        serList.forEach(v->{
            socialList.add(v.get("social_credit_code").toString());
        });
        String socialFilter;
        Integer supervise = 0;
        if (socialList.size() > 0){
            socialFilter = "social_credit_code in  ('" + StringUtils.join(socialList, "','") + "')";
            String superviseSql = "SELECT COUNT(*) FROM (SELECT * FROM unit_supervise WHERE  sup_code in  (SELECT sup_code FROM  unit_supervise_claim WHERE "+socialFilter+") UNION SELECT us.* FROM unit_supervise us LEFT JOIN unit_info ui ON ui.unit_id = us.sup_unit_id  WHERE ui.unit_code like '" + unitInfo.getUnitCode() + "%'  )a";
            supervise = jdbcTemplate.queryForObject(superviseSql, Integer.class);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("check",check);
        map.put("permit",permit);
        map.put("authority",authority);
        map.put("supervise",supervise);
        return map;
    }

    @Override
    public List<Map<String, Object>> getInfoUnitSupLevel(Long regionid) {
        if (regionid == null){
            regionid = 1L;
        }
        String unitFilter =  "ui.unit_code like '" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%'";
        String sql = "SELECT count(*) AS `count`, si.dict_item_name  FROM  unit_info ui  LEFT JOIN sys_dict_item si ON ui.sup_unit_level = si.dict_item_value WHERE  ui.delete_flag != 1 " +
                "AND si.dict_key = 'UNIT_MANUBRIUM_LEVEL'  AND "+unitFilter+" GROUP BY ui.sup_unit_level";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }

    @Override
    public List<Map<String, Object>> getInfoAuthorityDomain(Integer isSupervise, Long regionid) {
        if (regionid == null){
            regionid = 1L;
        }
        String unitTypeFilter = "u.unit_type_id in (2,4)";
        if (isSupervise == 1) {
            unitTypeFilter = " u.unit_type_id = 6";
        }else if(isSupervise == 2){
            unitTypeFilter = "  u.unit_type_id = 2 ";
        }
        String unitFilter =  " u.unit_code like '" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%'";
        String sql = "SELECT a.count, di.dict_item_name " +
                "FROM( SELECT  count(ud.domain_type_id) `count`,  ud.domain_type_id FROM  unit_info u,  unit_domain ud  WHERE  u.unit_id = ud.unit_id  AND "+unitTypeFilter+" AND "+unitFilter+" GROUP BY  ud.domain_type_id) a, " +
                "sys_dict_item di " +
                "WHERE a.domain_type_id = di.dict_item_value " +
                "AND di.dict_key = 'UNIT_DOMAIN' " +
                " ORDER BY a.count DESC " +
                "LIMIT 0,5;";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }

    @Override
    public  Map<String, Object>  getUnitLevelStat(Integer isSupervise, Long regionid) {

        List<Map<String, Object>> list = feignClientSystem.getUnitLevelStat(isSupervise,regionid);

        Map<String,Object> returnMap = new HashMap<>();
        if (list != null){
            Map<String, List<Map<String, Object>>> glist = list.stream().collect(Collectors.groupingBy(e -> e.get("levelName").toString()));
            List<Map<String, Object>> returnList = new ArrayList<>();
            glist.forEach((k,slist)->{
                List<Map<String, Object>> typeList = new ArrayList<>();
                Map<String,Object> nmap = new HashMap<>();
                IntSummaryStatistics sumcc = slist.stream().collect(Collectors.summarizingInt(e->e.get("count") !=null?Integer.valueOf(e.get("count").toString()):0));
                nmap.put("regionname",k);
                nmap.put("sumnum",sumcc.getSum());
                nmap.put("order",slist.get(0).get("display_order"));
                slist.forEach(v->{
                    Map<String,Object> typeMap = new HashMap<>();
                    typeMap.put("name",v.get("type_name"));
                    typeMap.put("code",v.get("typeID"));
                    typeMap.put("num",v.get("count")==null?0:v.get("count"));
                    typeList.add(typeMap);
                });
                nmap.put("types",typeList);
                returnList.add(nmap);
            });
            returnMap.put("children",returnList);
        }
        return returnMap;
    }

    @Override
    public List<Map<String, Object>> getInfoSubjectLevel(Long regionid) {

        String unitTypeFilter = " and unit_type_id in (2,4)  ";
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(SessionHelper.get().getUnitId() == 0 ? 1 : SessionHelper.get().getUnitId());
        UnitInfo unitInfo = getRegionInfo(unit.getRegionCode());
        String unitFilter = getUnitFilterString(regionid, unit);
        String filter = getDomainFilterString(unit);

        String sql = "SELECT b.dict_name AS lawName,a.unit_name AS dict_item_name,b.count,c.count as sup_unit_level_count ,c.dict_name FROM \n" +
                "(SELECT *FROM unit_info WHERE LENGTH(region_code) = 4 AND unit_type_id = 0) a\n" +
                "LEFT JOIN (SELECT regionCode, count(*) AS count  ,dict_name FROM(SELECT LEFT (region_code, 4) AS regionCode ,sd.dict_name FROM unit_info uu \n" +
                "LEFT JOIN sys_dict_item si ON uu.unit_type_id = si.dict_item_value\n" +
                "LEFT JOIN sys_dict sd ON si.dict_key = sd.dict_key \n" +
                "WHERE uu.delete_flag != 1 "+ unitTypeFilter + filter + unitFilter +" ) t GROUP BY\n" +
                "regionCode\n" +
                ") b ON a.region_code = b.regionCode\n" +
                "LEFT JOIN (SELECT count(*) AS `count`, si.dict_item_name,LEFT (ui.region_code, 4) AS regionCode ,sd.dict_name FROM unit_info ui\n" +
                "LEFT JOIN sys_dict_item si ON ui.sup_unit_level = si.dict_item_value\n" +
                "LEFT JOIN sys_dict sd ON si.dict_key = sd.dict_key\n" +
                "WHERE ui.delete_flag != 1\n" +
                " AND si.dict_key = 'UNIT_MANUBRIUM_LEVEL'\n" +
                ""+unitFilter+"" +
                "GROUP BY ui.sup_unit_level)c ON a.region_code = c.regionCode;";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);


        Map<String, Object> returnList = new HashedMap();
        Map<String, Object> statMap = new HashedMap();
        Map<String, Object> regionMap = new HashedMap();
        list.forEach(v -> {
            List<Map<String, Object>> typeList = new ArrayList<>();
            Map<String, Object> typeMap = new HashedMap();
            v.putIfAbsent("sumnum", "0");
            v.put("regioncode", regionIdFormat(v.get("regioncode").toString()));
            typeList.add(typeMap);
            v.put("types", typeList);
        });
        regionMap.put("regionid", unitInfo.getUnitId());
        regionMap.put("regioncode", regionIdFormat(unitInfo.getRegionCode()));
        regionMap.put("regionname", unitInfo.getUnitName());
        final int[] i = {0};
        list.stream().forEach(sun -> {
            i[0] += Integer.parseInt(sun.get("sumnum").toString());
        });
        regionMap.put("sumnum", i[0]);
        regionMap.put("seniorid", unitInfo.getSeniorId());
        statMap.put("children", list);
        statMap.put("region", regionMap);
        returnList.put("stat", statMap);
        return null;
    }

    @Override
    public List<Map<String, Object>> getInfoAuthorityPeopleDomain(Integer userType, Long regionid) {
        if (regionid == null){
            regionid = 1L;
        }
        String humanTypeFilter = " and u.human_type = '01'  ";
        if (userType == 1) {
            humanTypeFilter = " and u.human_type = '02' ";
        }
        String unitFilter =  "and u.unit_code like '" + unitInfoMapper.selectByPrimaryKey(regionid).getUnitCode() + "%'";
        String sql = " SELECT a.*, di.dict_item_name\n" +
                "FROM(  SELECT count(ud.domain_type_id) `count`, ud.domain_type_id FROM human_info u, unit_domain ud WHERE u.unit_id = ud.unit_id "+humanTypeFilter+unitFilter+" AND u.delete_flag != 1 GROUP BY ud.domain_type_id) a,\n" +
                "sys_dict_item di\n" +
                "WHERE a.domain_type_id = di.dict_item_value\n" +
                "AND di.dict_key = 'UNIT_DOMAIN'\n" +
                "ORDER BY a.count DESC\n" +
                "LIMIT 0,5;";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }

    @Override
    public List<Map<String,Object>> getInfoSubjectType(Long regionid) {
        List<Map<String, Object>> list = feignClientSystem.getUnitLevelStat(0,regionid);
        List<Map<String, Object>> returnList = new ArrayList<>();
        if (list != null){
            Map<String, List<Map<String, Object>>> glist = list.stream().collect(Collectors.groupingBy(e -> e.get("type_name").toString()));
            glist.forEach((k,slist)->{
                Map<String,Object> nmap = new HashMap<>();
                IntSummaryStatistics sumcc = slist.stream().collect(Collectors.summarizingInt(e->e.get("count") !=null?Integer.valueOf(e.get("count").toString()):0));
                nmap.put("dict_item_name",k);
                nmap.put("count",sumcc.getSum());
                returnList.add(nmap);
            });
        }
        return returnList;
    }

    private String getDomainFilterString(UnitInfo unit) {
        String filter = "";
        if (!"0".equals(unit.getUnitTypeId())) {
            String unitDomains = getUnitDomains(unit.getUnitId());
            if (StringUtils.isNotEmpty(unitDomains)) {
                filter = " and unit_id in ( select unit_id from unit_domain where domain_type_id in (" + unitDomains + ") ) ";
            }
        }
        return filter;
    }
    private String getUnitDomains(Long unitID) {
        List<SelectItem> selectItems = feignClientSystem.loadDomains(unitID);
        List<String> list = new ArrayList<>();
        for (SelectItem selectItem : selectItems) {
            list.add(selectItem.getValue().toString());
        }
        return StringUtils.join(list, ",");
    }
    private UnitInfo getRegionInfo(String regionCode) {
        Example example = new Example(UnitInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("unitTypeId", 0);
        criteria.andEqualTo("regionCode", regionCode);
        return unitInfoMapper.selectByExample(example).get(0);
    }

    private String getUnitFilterString(Long unitID, UnitInfo unit) {
        String unitFilter = "";
        if (unitID != null) {
            unitFilter = "and unit_code like '" + unitInfoMapper.selectByPrimaryKey(unitID).getUnitCode() + "%'";
        } else {
            UnitInfo unitInfo = getRegionInfo(unit.getRegionCode());
            unitFilter = "and unit_code like '" + unitInfo.getUnitCode() + "%'";
        }
        return unitFilter;
    }
    private String regionIdFormat(String regionId) {
        int n = 6;
        if (StringUtils.isNotBlank(regionId) && regionId.length()<n){
            return regionId+String.format("%1$0"+(n-regionId.length())+"d",0);
        }
        return regionId;
    }
}
